package weaver.aiyh_pcn.fadada;

import aiyh.utils.Util;
import aiyh.utils.entity.ApiConfigDetailDTO;
import aiyh.utils.entity.ApiConfigMainDTO;
import aiyh.utils.httpUtil.ResponeVo;
import aiyh.utils.mapUtil.ParaMap;
import aiyh.utils.sqlUtil.sqlResult.impl.PrepSqlResultImpl;
import aiyh.utils.zwl.common.ToolUtil;
import com.api.aiyh_pcn.fadada.dao.FaDDServiceMapping;
import com.api.aiyh_pcn.fadada.entity.FaDaDaConfigDTO;
import com.api.aiyh_pcn.fadada.util.FaDDRequestUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.h2.util.StringUtils;
import weaver.aiyh_pcn.fadada.entity.FileInfo;
import weaver.conn.RecordSet;
import weaver.file.ImageFileManager;
import weaver.hrm.User;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.RequestInfo;
import weaver.workflow.workflow.WorkflowVersion;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author EBU7-dev1-ayh
 * @create 2021/10/13 0013 19:41
 * 上传合同
 */


public class UploadFile2FaDDAction extends ToolUtil implements Action {
	private final FaDDServiceMapping faDDServiceMapping = new FaDDServiceMapping();
	private String workflowId;
	private String requestId;
	private String mainTableName;
	private String tableName;
	private final RecordSet rs = new RecordSet();
	private String contractField;
	private String customerNoField;
	private String customerNo;
	private String manySigned;
	private String manySignedNum;
	private String manySignedCompanyNo;
	private String signedField;
	private String signedValue;
	private String manySignedKeyWord;
	private List<Map<String, Object>> detailMaps;
	private Map<String, Object> mainMap;

	@Override
	public String execute(RequestInfo requestInfo) {
		this.workflowId = requestInfo.getWorkflowid();
		this.requestId = requestInfo.getRequestid();
		this.mainTableName = requestInfo.getRequestManager().getBillTableName();
		FaDaDaConfigDTO faDaDaConfigDTO = faDDServiceMapping.queryConfig(workflowId, 2);
		this.tableName = faDaDaConfigDTO.getCheckSource();
		super.writeErrorLog("进入action：workflowId:" + workflowId + ",requestId:" + requestId + "，mainTableName："
				+ mainTableName + ",tableName:" + tableName + ",contractField:" + contractField + ",customerNoField:" + customerNoField);
		String query = "select * from " + this.mainTableName + " where requestid = ?";
		RecordSet rs_1 = new RecordSet();
		rs_1.executeQuery(query, this.requestId);
		this.mainMap = Util.recordSet2Map(rs_1);
		String value = String.valueOf(mainMap.get(signedField));
		if(signedValue == null){
			signedValue = "";
		}
		if(!signedValue.equals(value)){
			return Action.SUCCESS;
		}
		try {
			this.createContract();
			try {
				this.signedContract();
			} catch (Exception e) {
				super.writeErrorLog("合同签署时发生错误：" + e);
				throw e;
			}
		} catch (Exception e) {
			e.printStackTrace();
			super.writeErrorLog("合同action出现错误，错误原因：" + e.toString());
			User user = requestInfo.getRequestManager().getUser();
			Map<String, String> map = Util.queryLanguage(1, user.getLanguage());
			requestInfo.getRequestManager().setMessagecontent(map.get("actionInfo"));
			requestInfo.getRequestManager().setMessageid(map.get("actionInfo"));
			return Action.FAILURE_AND_CONTINUE;
		}
//		this.signedContract();
		return Action.SUCCESS;
	}

	public void createContract() {
		String versionStringByWfid = WorkflowVersion.getVersionStringByWfid(workflowId);
		RecordSet rs = new RecordSet();
		rs.executeQuery("select * from uf_contract_config where workflow_type in ( " + versionStringByWfid + " ) and api_type = ?", 2);
		rs.next();
		ApiConfigMainDTO apiConfigMainDTO = Util.queryApiConfig(rs.getString("params_config"));
		String query = "select * from " + this.mainTableName + " where requestid = ?";
		RecordSet rs_1 = new RecordSet();
		rs_1.executeQuery(query, this.requestId);
		this.mainMap = Util.recordSet2Map(rs_1);
		String mainId = "";
		if (this.mainMap != null) {
			mainId = String.valueOf(this.mainMap.get("id"));
		} else {
			super.writeErrorLog("没有查询到相关的请求id的数据！");
		}
		query = "select * from " + this.tableName + " where mainid = ?";
		super.writeErrorLog(mainMap.toString());
		this.rs.executeQuery(query, mainId);
		this.detailMaps = Util.recordSet2MapList(this.rs);
		if (detailMaps == null) {
			super.writeErrorLog("查询明细失败！maps为null");
			throw  new RuntimeException("明细查询失败！maps为null");
		}
		super.writeErrorLog("明细表数据：" + detailMaps);
		for (Map<String, Object> detail : detailMaps) {
			List<FileInfo> fileInfos = this.contractHandle(detail, this.contractField);
			List<String> contractNoIds = new ArrayList<>();
			List<String> fileNoIds = new ArrayList<>();
			List<String> fileName = new ArrayList<>();
			if (fileInfos == null || fileInfos.size() == 0) {
				throw new RuntimeException("创建合同失败！");
			}
			for (FileInfo fileInfo : fileInfos) {
				ResponeVo contract = FaDDRequestUtils.createContract(fileInfo, apiConfigMainDTO.getApiUrl());
				Map<String, Object> result;
				try {
					Map<String, Object> entityMap = contract.getEntityMap();
					if (!"200".equals(String.valueOf(entityMap.get("code")))) {
						super.writeErrorLog("创建合同失败，错误信息:" + entityMap.get("message"));
						throw new RuntimeException("创建合同失败！");
					}
					result = (Map<String, Object>) entityMap.get("data");
					contractNoIds.add(Util.null2String(result.get("contractNo")));
					fileNoIds.add(Util.null2String(result.get("fileNo")));
					fileName.add(fileInfo.getImagefilename());
				} catch (JsonProcessingException e) {
					super.writeErrorLog(e.toString());
					throw new RuntimeException("创建合同失败！");
				}
			}
			String joinContract = String.join(",", contractNoIds);
			String joinFileNoIds = String.join(",", fileNoIds);
			String joinFileName = String.join(",", fileName);
			Map<String, Object> updateMap = ParaMap.create().put("contract_no", joinContract)
					.put("file_no", joinFileNoIds)
					.put("file_name", joinFileName);
			PrepSqlResultImpl sqlResult = Util.createSqlBuilder().updateSql(this.tableName, updateMap,
					Util.createPrepWhereImpl().whereAnd("id").whereEqual(detail.get("id")));
			super.writeErrorLog(sqlResult.getSqlStr() + "，参数：" + sqlResult.getArgs());
			rs.executeUpdate(sqlResult.getSqlStr(), sqlResult.getArgs());

		}
	}

	public List<FileInfo> contractHandle(Map<String, Object> detail, String contractField) {
		String fileIds = Util.null2String(detail.get(contractField));
		if (StringUtils.isNullOrEmpty(fileIds)) {
			fileIds = Util.null2String(this.mainMap.get(contractField));
		}
		if ("".equals(fileIds)) {
			return null;
		}
		List<FileInfo> fileInfos = faDDServiceMapping.queryImgFileIdByDocIds(fileIds);
		String customer = customerNo;
		;
		if (StringUtils.isNullOrEmpty(customerNo)) {

			String query = " select fadadaechapter from  uf_gyszsjb where vendorCode = ?";
			rs.executeQuery(query, String.valueOf(detail.get(customerNoField)));
			rs.next();
			customer = rs.getString(1);
		}
//		super.writeErrorLog("fileInfos:" + fileInfos + ",fileIds:" + fileIds + ",customerNo:" + customerNo);
		for (FileInfo fileInfo : fileInfos) {
			InputStream inputStreamById = ImageFileManager.getInputStreamById(fileInfo.getImagefileid());
			fileInfo.setFile(inputStreamById);
			String imagefilename = fileInfo.getImagefilename();
			if (imagefilename == null) {
				return null;
			}
			fileInfo.setContractExtension(imagefilename.substring(imagefilename.lastIndexOf(".")));
			fileInfo.setContractTitle(imagefilename);
//			fileInfo.setCustomerNo(Util.null2String(detail.get("customer_no")));
//			fileInfo.setCustomerNo("e23deb7a29714d0da5b806665ab3e2f8");
			fileInfo.setCustomerNo(Util.null2String(customer));
			if (StringUtils.isNullOrEmpty(fileInfo.getCustomerNo())) {
				fileInfo.setCustomerNo(Util.null2String(detail.get("companyno")));
			}
			fileInfo.setUploadType(1);
		}
		return fileInfos;
	}

	public void signedContract() {
		String query = "select * from " + this.tableName + " where mainid = ?";
		this.rs.executeQuery(query, String.valueOf(mainMap.get("id")));
		this.detailMaps = Util.recordSet2MapList(this.rs);
		if (detailMaps == null) {
			super.writeErrorLog("查询明细失败！maps为null");
			return;
		}
		FaDaDaConfigDTO faDaDaConfigDTO = faDDServiceMapping.queryConfig(workflowId, 3);
		ApiConfigMainDTO apiConfigMainDTO = Util.queryApiConfigTree(faDaDaConfigDTO.getParamsConfig());
		List<Map<String, Object>> dataArr = new ArrayList<>();
		String detailTable;
		String dt = this.tableName.substring(this.tableName.indexOf("_dt") + 3);
		detailTable = "detail_" + dt;
		for (Map<String, Object> detailMap : this.detailMaps) {
			Map<String, Object> dataMap = new HashMap<>();
			for (Map.Entry<String, Object> entry : detailMap.entrySet()) {
				dataMap.put(detailTable + "." + entry.getKey(), entry.getValue());
			}
			for (Map.Entry<String, Object> entry : this.mainMap.entrySet()) {
				dataMap.put("main" + "." + entry.getKey(), entry.getValue());
			}
			dataArr.add(dataMap);
		}
		List<Map<String, Object>> maps = objectAndListHandle(apiConfigMainDTO.getDetails(), dataArr);
		int n = 0;
		for (Map<String, Object> map : maps) {
			int contractNum = 0;
			if ("true".equals(manySigned)) {
				String[] companyNos = manySignedCompanyNo.split(",");
				String[] keyWords = manySignedKeyWord.split(",");
				for (int i = 0; i < companyNos.length; i++) {
					String companyNo = String.valueOf(detailMaps.get(n).get(companyNos[i]));
					String keyWord = String.valueOf(detailMaps.get(n).get(keyWords[i]));
					map.put("companyNo", companyNo);
					map.put("locateKey", keyWord);
					String contractNos = Util.null2String(map.get("contractNo"));
					String[] split = contractNos.split(",");
					for (String s : split) {
						map.put("contractNo", s);
						ResponeVo responeVo = FaDDRequestUtils.signedContract(map, apiConfigMainDTO.getApiUrl());
						contractNum++;
						Map<String, Object> response = null;
						try {
							response = responeVo.getEntityMap();
						} catch (JsonProcessingException e) {
							e.printStackTrace();
						}
						if (!"200".equals(response.get("code"))) {
							super.writeErrorLog("法大大接口签署合同失败！");
						}
					}
				}
			} else {
				String contractNos = Util.null2String(map.get("contractNo"));
				String[] split = contractNos.split(",");
				for (String s : split) {
					map.put("contractNo", s);
					ResponeVo responeVo = FaDDRequestUtils.signedContract(map, apiConfigMainDTO.getApiUrl());
					contractNum++;
					Map<String, Object> response = null;
					try {
						response = responeVo.getEntityMap();
					} catch (JsonProcessingException e) {
						e.printStackTrace();
					}
					if (!"200".equals(response.get("code"))) {
						super.writeErrorLog("法大大接口签署合同失败！");
					}
				}
			}
//			更新合同数量
			Map<String, Object> updateMap = new HashMap<>();
			updateMap.put("contract_num", contractNum);
			PrepSqlResultImpl sqlResult = Util.createSqlBuilder().updateSql(tableName, updateMap,
					Util.createPrepWhereImpl().whereAnd("id").whereEqual(String.valueOf(detailMaps.get(n).get("id"))));
			rs.executeUpdate(sqlResult.getSqlStr(), sqlResult.getArgs());
			n++;
		}
	}

	private List<Map<String, Object>> objectAndListHandle(List<ApiConfigDetailDTO> treeList, List<Map<String, Object>> dataArr) {
		List<Map<String, Object>> params = new ArrayList<>();
		for (Map<String, Object> dataMap : dataArr) {
			Map<String, Object> param = new HashMap<>();
			for (ApiConfigDetailDTO apiConfigDetailDTO : treeList) {
				Object value;
				if (apiConfigDetailDTO.getParamType() == 3) {
					Map<String, Object> map = new HashMap<>();
//                  object类型
					for (ApiConfigDetailDTO child : apiConfigDetailDTO.getChildren()) {
						if (child.getChildren() == null || child.getChildren().size() == 0) {
//							  handleChild(child.getChildren(), dataMap)
							map.put(child.getParamName(), changeRuleHandle(child, dataMap));
						} else {
							map.put(child.getParamName(), handleChild(child.getChildren(), dataMap));
						}
					}
					value = map;
				} else if (apiConfigDetailDTO.getParamType() == 4) {
					String sql = apiConfigDetailDTO.getArraySql();
					String parsingSq = Util.parsingSq(sql, dataMap);
//				    list类型
					if (parsingSq.contains("delete") || parsingSq.contains("update") ||
							parsingSq.contains("exec") || parsingSq.contains("drop") ||
							parsingSq.contains("truncate")) {
						value = new ArrayList<>();
					} else {
						RecordSet rs = new RecordSet();
						rs.executeQuery(parsingSq.replace("ｓｅｌｅｃｔ", "select"));
						value = Util.recordeSet2Array(rs, String.class);
					}
				} else {
					value = changeRuleHandle(apiConfigDetailDTO, dataMap);
				}
				param.put(apiConfigDetailDTO.getParamName(), value);
			}
			params.add(param);
		}
		return params;
	}

	private Object handleChild(List<ApiConfigDetailDTO> children, Map<String, Object> dataMap) {
		Map<String, Object> params = new HashMap<>();
		for (ApiConfigDetailDTO child : children) {
			Object value;
			if (child.getChildren() != null) {
				value = handleChild(child.getChildren(), dataMap);
			} else {
				value = changeRuleHandle(child, dataMap);
			}
			params.put(child.getParamName(), value);
		}
		return params;
	}

	private Object changeRuleHandle(ApiConfigDetailDTO apiConfigDetailDTO, Map<String, Object> dataMap) {
		Object value;
		String tableName;
		String table;
		String sql;
		String resultSql;
//			判断参数的转换规则
		switch (apiConfigDetailDTO.getChangeRule()) {
			case 0:
//					不转换
			case 2:
//					流程字段值
				table = apiConfigDetailDTO.getTablename();
				if (!table.contains("_dt")) {
//			        表示字段属于主表
					tableName = "main";
				} else {
//			        字段属于明细表
					String dt = table.substring(table.indexOf("_dt") + 3);
					tableName = "detail_" + dt;
				}
//				super.writeErrorLog("参数值：" + dataMap.get(tableName + "." + apiConfigDetailDTO.getWorkflowField()) + ",参数map：" + dataMap);
				value = dataMap.get(tableName + "." + apiConfigDetailDTO.getWorkflowField());
				break;
			case 1:
//					固定值
				value = apiConfigDetailDTO.getParamValue();
				break;
			case 3:
//					系统日期
				value = Util.getTime("yyyy-MM-dd");
				break;
			case 4:
//					系统时间
				value = Util.getTime("HH:mm:ss");
				break;
			case 5:
//					系统日期-时间
				value = Util.getTime("yyyy-MM-dd HH:mm:ss");
				break;
			case 6:
//					自定义SQL
			case 7:
//					流程字段转SQL
				sql = apiConfigDetailDTO.getParamValue();
				resultSql = Util.parsingSq(sql, dataMap);
				if (resultSql.contains("delete ") || resultSql.contains("update ") ||
						resultSql.contains("exec ") || resultSql.contains("drop ") ||
						resultSql.contains("truncate ")) {
					value = null;
				} else {
					RecordSet rs = new RecordSet();
					rs.executeQuery(resultSql.replace("ｓｅｌｅｃｔ", "select"));
					rs.next();
					value = Util.null2String(rs.getString(1));
				}
				break;
			case 8:
//
//					流程名称
				value = Util.getWorkflowNameById(String.valueOf(dataMap.get("workflowid")));
				break;
			case 9:
//
//					请求标题
				value = Util.getRequestTitleById(String.valueOf(dataMap.get("requestid")));
				break;
			case 10:
//
//					流程requestId
				value = dataMap.get("requestid");
				break;
			default:
				value = null;
				break;
		}
		if (apiConfigDetailDTO.getParamType() == 1) {
//			Integer
			value = Integer.parseInt(String.valueOf(value));
		} else if (apiConfigDetailDTO.getParamType() == 2) {
//          Boolean
			value = Boolean.parseBoolean(String.valueOf(value));
		}
		return value;
	}

	public String getCustomerNo() {
		return customerNo;
	}

	public void setCustomerNo(String customerNo) {
		this.customerNo = customerNo;
	}

	public String getCustomerNoField() {
		return customerNoField;
	}

	public void setCustomerNoField(String customerNoField) {
		this.customerNoField = customerNoField;
	}

	public String getContractField() {
		return contractField;
	}

	public void setContractField(String contractField) {
		this.contractField = contractField;
	}

	public String getManySigned() {
		return manySigned;
	}

	public void setManySigned(String manySigned) {
		this.manySigned = manySigned;
	}

	public String getManySignedNum() {
		return manySignedNum;
	}

	public void setManySignedNum(String manySignedNum) {
		this.manySignedNum = manySignedNum;
	}

	public String getManySignedCompanyNo() {
		return manySignedCompanyNo;
	}

	public void setManySignedCompanyNo(String manySignedCompanyNo) {
		this.manySignedCompanyNo = manySignedCompanyNo;
	}

	public String getManySignedKeyWord() {
		return manySignedKeyWord;
	}

	public void setManySignedKeyWord(String manySignedKeyWord) {
		this.manySignedKeyWord = manySignedKeyWord;
	}

	public String getSignedField() {
		return signedField;
	}

	public void setSignedField(String signedField) {
		this.signedField = signedField;
	}

	public String getSignedValue() {
		return signedValue;
	}

	public void setSignedValue(String signedValue) {
		this.signedValue = signedValue;
	}
}
